import { Camera, LinearSRGBColorSpace, PerspectiveCamera, Scene, WebGLRenderer } from "three";
import Stats from 'three/examples/jsm/libs/stats.module.js';

export class ThreeRenderSystem {
  private _renderer: WebGLRenderer;
  private _innerContainer: HTMLElement;
  private _width: number = 0;
  private _height: number = 0;
  private _scene: Scene | null = null;
  private _camera: Camera | null = null;
  private _containerDom: HTMLElement | null = null;
  private _stats: Stats | null = null;
  private _registerListener: boolean = false;

  constructor() {
    const renderer = new WebGLRenderer({ antialias: true });
    renderer.setPixelRatio( window.devicePixelRatio ); // TODO: Use player.setPixelRatio()
		renderer.outputColorSpace = LinearSRGBColorSpace;

    const dom = document.createElement( 'div' );
		dom.appendChild( renderer.domElement );

		this._innerContainer = dom;
    this._renderer = renderer;
  }



  bind(containerDom: HTMLElement, scene: Scene) {
    this._containerDom = containerDom;
    this._scene = scene;

    // 自动设置宽高度
    this.setSizeFromContainer(containerDom);

    // 更新渲染dom容器和canvas宽高
    this.updateRenderSize();

    // 更新相机
    this.updateCamera();

    containerDom.appendChild(this._innerContainer);

    this.initListener();
  }

  setSizeFromContainer(containerDom: HTMLElement) {
    this._width = containerDom.offsetWidth;
    this._height = containerDom.offsetHeight;
  }

  updateRenderSize() {
    const innerCo = this._innerContainer;
    // 设置宽高
    innerCo.style.width = this._width + "px";
    innerCo.style.height = this._height + "px";

    // 设置渲染canvas宽高
    this._renderer.setSize(this._width, this._height);
  }

  /** 更新或初始化相机
   */
  updateCamera() {
    // camera
    let camera: Camera | null = this._camera;
    if (camera === null) {
      camera = new PerspectiveCamera(45, this._width / this._height, 0.1, 5000);
      camera.position.set(0,0,50);
      this._camera = camera;
    }
    else {
      if (camera instanceof PerspectiveCamera) {
        camera.aspect = this._width / this._height;
        camera.updateProjectionMatrix();
      }
      else {
        // 后续正交相机适配
        console.warn("update nothing")
      }

    }
  }

  /** 添加监视器
   */
  useStats() {
    const stats = new Stats();
    stats.showPanel(0); // 1 显示 GPU 时间
    // 设置监视器位置
    stats.dom.style.position = "absolute";
    stats.dom.style.left = "0px";
    stats.dom.style.top = "0px";
    document.body.appendChild(stats.dom);
    this._stats = stats;
  }

  render() {
    const scene = this._scene;
    const camera = this._camera;
    if (scene && camera) {
      this._stats && this._stats.begin();

      this._renderer.render(scene, camera);

      this._stats && this._stats.end();
    }
    else {
      console.error("请先绑定场景和相机");
      throw new Error("请先绑定场景和相机");
    }
  }


  //#region 挂载监听器
  initListener() {
    const renderCanvas = this._renderer.domElement;
    renderCanvas.addEventListener("mousemove", this.mouseMoveHandler.bind(this))
  }

  private mouseMoveHandler(e: MouseEvent) {
    this.render();
  }

  //#endregion
}
